﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Top.Data;
using Top.PointStore.Business;
using System.IO;
using System.Collections;
using System.Data;
//using Aspose.Cells;
using Top.Web;
using System.Collections.Concurrent;
using Top.Redis;
using Top.Base.RedisKey;
using Top.Base.Common;
using Top.Base.DataBase;
using Top.Core;
using Top.Web.Api;
namespace Top.PointStore.LuckTurntable
{
    /*功能说明:大转盘操作操作管理类
    *版本:
    *参与人:王士锋
    *修改日期:2015.3.4
    */
    public static class LuckTurntableManager
    {
        private static Top.Common.TopCacheUtil cacheUtil = new Top.Common.TopCacheUtil();

        static LuckTurntableManager()
        {
            InitialLuckProductList();
        }

        /// <summary>
        /// 初始化化参与抽奖商品数据
        /// </summary>
        private static ConcurrentDictionary<int, LuckProduct> dicLuckProducts = new ConcurrentDictionary<int, LuckProduct>();
        private static bool isInitialLuckProducts = false;
        private static object lockForInitialLuckProducts = new object();

        /// <summary>
        /// 初始化抽奖商品
        /// </summary>
        /// <returns></returns>
        public static ConcurrentDictionary<int, LuckProduct> InitialLuckProductList()
        {
            try
            {
                const string sql = @"select * from T_LuckProduct";
                DataTable dt = SQLHelper.ExecuteTable(sql);
                if (dt.Rows.Count <= 0)
                {
                    return dicLuckProducts;
                }

                if (!isInitialLuckProducts && !dicLuckProducts.Any())
                {
                    lock (lockForInitialLuckProducts)
                    {
                        if (!isInitialLuckProducts && !dicLuckProducts.Any())
                        {
                            #region 遍历组装list集合

                            foreach (DataRow row in dt.Rows)
                            {
                                LuckProduct model = new LuckProduct();
                                if (row["Angle"] != null && row["Angle"].ToString() != "")
                                {
                                    model.Angle = int.Parse(row["Angle"].ToString());
                                }
                                if (row["Name"] != null)
                                {
                                    model.Name = row["Name"].ToString();
                                }
                                if (row["Chance"] != null && row["Chance"].ToString() != "")
                                {
                                    model.Chance = int.Parse(row["Chance"].ToString());
                                }
                                if (row["Count"] != null && row["Count"].ToString() != "")
                                {
                                    model.Count = int.Parse(row["Count"].ToString());
                                }
                                if (row["Point"] != null && row["Point"].ToString() != "")
                                {
                                    model.Point = int.Parse(row["Point"].ToString());
                                }
                                if (row["Description"] != null)
                                {
                                    model.Description = row["Description"].ToString();
                                }
                                if (row["Kid"] != null && row["Kid"].ToString() != "")
                                {
                                    model.Kid = int.Parse(row["Kid"].ToString());
                                }
                                if (row["Rate"] != null && row["Rate"].ToString() != "")
                                {
                                    model.Rate = int.Parse(row["Rate"].ToString());
                                }
                                if (row["MaxCount"] != null && row["MaxCount"].ToString() != "")
                                {
                                    model.MaxCount = int.Parse(row["MaxCount"].ToString());
                                }
                                if (row["LuckCount"] != null && row["LuckCount"].ToString() != "")
                                {
                                    model.LuckCount = int.Parse(row["LuckCount"].ToString());
                                }

                                dicLuckProducts.TryAdd(model.Kid, model);
                            }

                            #endregion
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Trace.TraceError(string.Format("Redis操作 类名[LuckTurntableManager] 方法名[GetLuckProductList] 异常信息：{0}", ex.ToString()));
            }

            return dicLuckProducts;
        }
       
        /// <summary>
        /// 获取抽奖商品列表
        /// </summary>
        /// <returns></returns>
        public static ConcurrentDictionary<int, LuckProduct> GetLuckProductList()
        {
            if (dicLuckProducts.Any())
            {
                //LuckProduct outLuckProduct = null;
                //foreach (var item in dicLuckProducts)
                //{
                //    if (item.Value.LuckCount == item.Value.MaxCount && item.Value.Count <= 0)
                //    {
                //        dicLuckProducts.TryRemove(item.Key,out outLuckProduct);
                //    }
                //}
                return dicLuckProducts;
            }

            return InitialLuckProductList();
        }

        /// <summary>
        /// 统计抽奖商品所中奖个数
        /// </summary>
        /// <returns></returns>
        public static async Task<IList<LuckCount>> GetLuckCountToday()
        {
            const string sql = @"select 
                    count(1) as Count,LuckProductKid as Kid
                     from T_LuckRecord
                     where LuckProductKid in (select LuckProductKid from T_LuckRecord)
                     and CreateTime> {0}
                     and CreateTime< {1}
                     group by LuckProductKid";
            using (var db = new DbTour())
            {
                return await db.Sql(sql, DateTime.Now.Date, DateTime.Now.Date.AddDays(1)).ToList<LuckCount>();
            }
        }


        private static System.Collections.Concurrent.ConcurrentDictionary<Guid, int> IsUserBuying = new System.Collections.Concurrent.ConcurrentDictionary<Guid, int>(4 * Environment.ProcessorCount, 800);
        private static System.Threading.SpinLock spinLock = new System.Threading.SpinLock();
        private static System.Collections.Concurrent.ConcurrentDictionary<int, int> dicUserTurnCount = new System.Collections.Concurrent.ConcurrentDictionary<int, int>();

        public static async Task<LuckyResult> Turn(OAuthUser user, bool isUsePoint)
        {
            //TODO 每个经纪人只能参与一次，从中奖纪录来判断，如果已经参与过，提示您已参与
            //TODO 不判断分销公司
            //TODO 每个奖品设置当天最大中奖数量
            //TODO ！！如果当天或者所有的奖品都已经对换，则提示今日商品已兑完，请明天再来


            #region 初始化中奖商品

            var res = new LuckyResult();
            res.IsUsePoint = isUsePoint;
            res.State = 1;
            res.isWin = true;

            var notWin = new LuckProduct()
            {
                Angle = 0,
                Chance = 0,
                Count = 0,
                Description = "感谢参与",
                Kid = 0,
                LuckCount = 0,
                MaxCount = 0,
                Name = "感谢参与",
                Point = 0,
                Rate = 1
            };

            #endregion

            #region 控制抽奖时间范围

            #region 控制每天抽奖时间 //

            //string luckyTime = Configs.AppSettings["LuckyTime"].ToString();

            //int startTime = Convert2.ToInt32(luckyTime.Split('|').FirstOrDefault(), 9);
            //int endTime = Convert2.ToInt32(luckyTime.Split('|').LastOrDefault(), 18);

            //int nowHour = DateTime.Now.Hour;
            //if (nowHour < startTime || nowHour > endTime)
            //{
            //    res.Message = "8.20号9:00开始抽奖,敬请期待";
            //    res.State = -1;
            //    res.isWin = false;
            //    res.LuckProduct = notWin;
            //    return res;
            //}

            #endregion


            #region 七夕活动需开启  //

            //DateTime nowDate = DateTime.Now;
            //DateTime startDate = Convert2.ToDateTime("2015-8-20 10:00");
            //DateTime endDate = Convert2.ToDateTime("2015-8-21 00:00");

            //if (nowDate < startDate)
            //{
            //    res.Message = "8.20号10:00开始抽奖,敬请期待";
            //    res.State = -1;
            //    res.isWin = false;
            //    res.LuckProduct = notWin;
            //    return res;
            //}

            //if (nowDate >= endDate)
            //{
            //    res.Message = "本次活动已结束，敬请期待下次";
            //    res.State = -1;
            //    res.isWin = false;
            //    res.LuckProduct = notWin;
            //    return res;
            //}

            #endregion


            #region 中秋活动时间 //

            //DateTime nowDate = DateTime.Now;
            //DateTime startDate = Convert3.To<DateTime>("2015-9-27 10:11");
            //DateTime endDate = Convert3.To<DateTime>("2015-9-28 00:00");

            //if (nowDate < startDate)
            //{
            //    res.Message = "9.27号10:11开始抽奖,敬请期待";
            //    res.State = -1;
            //    res.isWin = false;
            //    res.LuckProduct = notWin;
            //    return res;
            //}

            //if (nowDate >= endDate)
            //{
            //    res.Message = "本次活动已结束，敬请期待下次";
            //    res.State = -1;
            //    res.isWin = false;
            //    res.LuckProduct = notWin;
            //    return res;
            //}

            #endregion

            #endregion


            //限制同个用户多次请求并发处理
            if (!IsUserBuying.TryAdd(user.UserToken, 1))
            {
                res.Message = "抽奖人数排队中,请稍后再试!";
                res.State = -4;
                res.isWin = false;
                res.LuckProduct = notWin;
                return res;
            }


            #region 获取抽奖商品列表

            var luckProducts = GetLuckProductList();

            ///123456789
            int usePoint = -100; //扣除积分
            //if (broker.F_IsDistribute ?? false)
            //{
            //    usePoint = usePoint * 10;
            //}

            #endregion

            #region 520活动//

            //var exchangeNotDisplay = new[]
            //{
            //    "谢谢参与",
            //    "200积分",
            //    "500积分"
            //};

            //var luckRecordNotDisplay = new[]
            //{
            //    "谢谢参与"
            //};


            //var winList = new[]
            //{
            //    "200积分",
            //    "500积分",
            //    "10元话费",
            //    "20元话费",
            //    "30元话费",
            //    "50元话费",
            //    "100元话费"
            //};

            //var autoList = new[]
            //{
            //    "200积分",
            //    "500积分"
            //};

            //var productTipList = new[]
            //{
            //    "10元话费",
            //    "20元话费",
            //    "30元话费",
            //    "50元话费",
            //    "100元话费"
            //};

            #endregion

            #region 端午节//

            //var exchangeNotDisplay = new[]
            //{
            //    "谢谢参与",
            //    "100积分",
            //    "200积分",
            //    "500积分"
            //};

            //var luckRecordNotDisplay = new[]
            //{
            //    "谢谢参与",
            //    "再来一次"
            //};


            //var winList = new[]
            //{
            //    "100积分",
            //    "200积分",
            //    "500积分",
            //    "超市卡50元",
            //    "粽子礼盒",
            //    "坚果礼盒"
            //};

            //var autoList = new[]
            //{
            //    "100积分",
            //    "200积分",
            //    "500积分"
            //};

            //var productTipList = new[]
            //{
            //    "超市卡50元",
            //    "粽子礼盒",
            //    "坚果礼盒"
            //};

            #endregion

            #region 七夕节//

            //var exchangeNotDisplay = new[]
            //{
            //    "3000积分",
            //    "2000积分",
            //    "1000积分",
            //    "500积分"
            //};

            //var luckRecordNotDisplay = new[]
            //{
            //    "谢谢参与",
            //    "再来一次"
            //};


            //var winList = new[]
            //{
            //    "3000积分",
            //    "2000积分",
            //    "1000积分",
            //    "500积分",
            //    "仿陶瓷情侣杯",
            //    "德芙巧克力",
            //    "杜蕾斯一盒",
            //    "销冠手机"
            //};

            //var autoList = new[]
            //{
            //    "3000积分",
            //    "2000积分",
            //    "1000积分",
            //    "500积分"
            //};

            //var productTipList = new[]
            //{
            //    "仿陶瓷情侣杯",
            //    "德芙巧克力",
            //    "杜蕾斯一盒",
            //    "销冠手机"
            //};

            #endregion

            #region 中秋节 //

            //var exchangeNotDisplay = new[]
            //{
            //    "1000积分",
            //    "500积分"
            //};

            //var luckRecordNotDisplay = new[]
            //{
            //    "谢谢参与",
            //    "再来一次"
            //};

            //var winList = new[]
            //{
            //    "1000积分",
            //    "500积分",
            //    "4G无线键盘鼠标套装",
            //    "海盗狗竹炭包",
            //    "打火机",
            //    "数据线"
            //};

            //var autoList = new[]
            //{
            //    "1000积分",
            //    "500积分"
            //};

            //var productTipList = new[]
            //{
            //    "4G无线键盘鼠标套装",
            //    "海盗狗竹炭包",
            //    "打火机",
            //    "数据线"
            //};

            #endregion

            try
            {

                #region 中秋节

                //Dictionary<string, string> dicExchangeNotDisplay = new Dictionary<string, string>();
                //dicExchangeNotDisplay.Add("1000积分", string.Empty);
                //dicExchangeNotDisplay.Add("500积分", string.Empty);

                Dictionary<string, string> dicLuckRecordNotDisplay = new Dictionary<string, string>();
                dicLuckRecordNotDisplay.Add("谢谢参与", string.Empty);
                dicLuckRecordNotDisplay.Add("再来一次", string.Empty);

                Dictionary<string, string> dicWinList = new Dictionary<string, string>();
                dicWinList.Add("1000积分", string.Empty);
                dicWinList.Add("500积分", string.Empty);
                dicWinList.Add("4G无线键盘鼠标套装", string.Empty);
                dicWinList.Add("海盗狗竹炭包", string.Empty);
                dicWinList.Add("打火机", string.Empty);
                dicWinList.Add("数据线", string.Empty);

                //Dictionary<string, string> dicAutoList = new Dictionary<string, string>();
                //dicAutoList.Add("1000积分", string.Empty);
                //dicAutoList.Add("500积分", string.Empty);


                //Dictionary<string, string> dicProductTipList = new Dictionary<string, string>();
                //dicProductTipList.Add("4G无线键盘鼠标套装", string.Empty);
                //dicProductTipList.Add("海盗狗竹炭包", string.Empty);
                //dicProductTipList.Add("打火机", string.Empty);
                //dicProductTipList.Add("数据线", string.Empty);

                #endregion

                #region 判断当天抽奖机会是否用完

                //gc-f   1、result > 0 统计正常 2、result < 0 redis出现异常
                var joinCount = await JoinCount(user.UserToken.ToString());
                if (joinCount < 0)
                {
                    res.Message = "抽奖人数过多,请稍后再试!";
                    res.State = -4;
                    res.isWin = false;
                    res.LuckProduct = notWin;
                    return res;
                }


                int luckRecordNumByBrokerKid = await GetLuckRecord(user.UserToken.ToString(), 249);
                if (luckRecordNumByBrokerKid > 0)
                {
                    joinCount--;
                }
                else
                {
                    //int lotteryNum = Convert2.ToInt32(Top.Web.Configs.AppSettings["LotteryNum"].ToString(), 2);
                    int lotteryNum = 2;
                    if (joinCount >= lotteryNum)
                    {
                        res.Message = "您的抽奖机会已用完!";
                        res.State = -1;
                        res.isWin = false;
                        res.LuckProduct = notWin;
                        return res;
                    }

                }

                T_PointMain_new brokerPoint = await LuckProductManager.GetBrokerPoint(user);
                //判断剩余积分是否具有购买能力
                if (brokerPoint.F_PointBalance < -usePoint)
                {
                    res.Message = "积分不足";
                    res.State = -2;
                    res.isWin = false;
                    res.LuckProduct = notWin;
                    return res;

                }

                #endregion

                #region 处理业务


                var totalCountAll = 0;
                var totalCount = 0;
                foreach (var item in dicLuckProducts)
                {
                    totalCountAll += item.Value.Count;
                    totalCount += (item.Value.MaxCount - item.Value.LuckCount);
                }

                //foreach (var luckProduct in luckProducts)
                //{
                //    //if (luckProduct.Name == "再来一次") continue;
                //    totalCountAll += luckProduct.Count;
                //    totalCount += (luckProduct.MaxCount - luckProduct.LuckCount);
                //}

                if (totalCountAll <= 0 || totalCount <= 0)
                {
                    //res.Message = "今天的奖品兑完啦,明天再来吧！";
                    //res.Message = "手慢啦，该奖品已抽完啦！";
                    res.Message = "本次活动奖品已抽完，敬请期待下次.";
                    res.State = -1;
                    res.isWin = false;
                    res.LuckProduct = notWin;
                    return res;
                }

                //if (string.IsNullOrWhiteSpace(user.UserToken.ToString()))
                //{
                //    res.Message = "经纪人不存在！";
                //    res.State = -1;
                //    res.isWin = false;
                //    res.LuckProduct = notWin;
                //    return res;
                //}

                if (luckProducts.Count == 0)//奖品不存在
                {
                    res.Message = "奖品不存在";
                    res.State = -3;
                    res.isWin = false;
                    res.LuckProduct = notWin;
                    return res;
                }

                res.LuckProduct = GetRand();//计算概率 返回是否中奖信息 
                if (res.LuckProduct == null)
                {
                    res.Message = "出问题啦,再试一次吧";
                    res.State = -4;
                    res.isWin = false;
                    res.LuckProduct = notWin;
                    return res;
                }

                if (res.LuckProduct.LuckCount >= res.LuckProduct.MaxCount)
                {
                    res.LuckProduct.Description = "该礼品已抽完，未扣积分，再来一次.";
                    res.LuckProduct = res.LuckProduct;//感谢参与
                    res.Message = "该礼品已抽完，未扣积分，再来一次.";
                    res.State = 2;
                    notWin.Description = "该礼品已抽完，未扣积分，再来一次.";
                    res.isWin = false;
                    return res;
                }

                //扣除积分
                if (res.IsUsePoint)//判断本次是否使用积分
                {
                    usePoint = 0;
                    res.IsUsePoint = false;
                }

                if (res.LuckProduct.Name == "再来一次")//如果是再来一次,下次抽奖将不使用积分
                {
                    res.IsUsePoint = true;
                }


                //判断中奖商品是否有库存 gc
                if (res.LuckProduct.Count <= 0)
                {
                    res.Message = "该礼品已抽完，未扣积分，再来一次.";
                    res.State = 2;
                    notWin.Description = "该礼品已抽完，未扣积分，再来一次.";
                    res.isWin = true;
                    res.LuckProduct = notWin;//感谢参与

                    //===参与活动记录一次机会,不扣减库存及积分，注销此行代码===
                    //return res;
                }

                #endregion

                #region


                var exchangeKid = 0;

                //构造数据
                T_LuckRecordExpand luckRecord = new T_LuckRecordExpand();
                luckRecord.UserToken = user.UserToken.ToString();
                luckRecord.ExchangeKid = exchangeKid;
                luckRecord.LuckProductKid = res.LuckProduct.Kid;
                luckRecord.OrderNo = DateTime.Now.ToString("yyyyMMddHHmmfff");
                luckRecord.UserName = user.Name ?? user.NickName;
                luckRecord.PhoneNumber = user.Phone;
                luckRecord.F_CompanyName = "";// user.F_BrokerCompanyName;
                luckRecord.F_IsDisplay = dicLuckRecordNotDisplay.ContainsKey(res.LuckProduct.Name) ? 0 : 1;
                luckRecord.IsWin = dicWinList.ContainsKey(res.LuckProduct.Name) ? 1 : 0;
                luckRecord.CreateTime = DateTime.Now;
                luckRecord.F_ProductName = res.LuckProduct.Name;

                #region 扣除积分 更新库存

                //抽中奖品，扣积分
                if (res.LuckProduct.Count > 0)
                {
                    //幸运大转盘抽奖消耗 gc*
                    int resultID = LuckProductManager.UpdateBrokerPoint(brokerPoint,user, usePoint, "broker.pointluck.cash");
                    if (resultID <= 0)
                    {
                        res.Message = "感谢参与";//感谢参与
                        res.isWin = false;
                        notWin.Description = "手慢啦，该奖品已抽完啦！";
                        res.LuckProduct = notWin;
                        return res;
                    }

                }
                //更新奖品数量    1、result > 0 统计正常   2、result <= 0 redis出现异常 lock*--内部有spinlock
                int updateCount = LuckTurntableManager.UpdateCount(res.LuckProduct.Kid);
                if (updateCount <= 0)
                {
                    res.Message = "感谢参与";//感谢参与
                    res.isWin = false;
                    notWin.Description = "手慢啦，该奖品已抽完啦！";
                    res.LuckProduct = notWin;
                    LuckProductManager.UpdateBrokerPoint(brokerPoint, user ,-usePoint, "broker.pointluck.refund");//退回积分
                    return res;
                }

                #endregion

                //开启事务

                #region 插入中奖纪录 redis
                exchangeKid = await AddLuckyRecord(luckRecord, user);//返回中奖纪录ID
                if (exchangeKid <= 0)
                {
                    res.Message = "未抽中奖品,继续努力!";
                    res.State = -8;
                    res.isWin = false;
                    res.LuckProduct = notWin;//感谢参与       
                    LuckProductManager.UpdateBrokerPoint(brokerPoint, user, -usePoint, "broker.pointluck.refund");//退回积分
                    return res;
                }

                //发布订阅机制
                //抽中“谢谢参与”或“再来一次”，不执行订阅机制 
                if (dicWinList.ContainsKey(res.LuckProduct.Name) && res.LuckProduct.Count > 0)
                {
                    long resultPubID = await RedisHelper.Publish("TopsHandleLuckRecordWindowsService", string.Format("{0}-{1}", exchangeKid.ToString(), user.UserToken));
                    if (resultPubID <= 0)
                    {
                       ErrorLog.WriteLog(string.Format("中奖编号：{0},物品名称：{1}，提示信息：发布失败", exchangeKid.ToString(), res.LuckProduct.Name));
                    }
                }

                #endregion

                #region 如果是虚拟物品增加积分 //

                //if (res.LuckProduct.Point > 0)
                //{
                //    await PointManager.UpdateBrokerPoint(broker.Kid, res.LuckProduct.Point, "broker.pointluck.award", db);//幸运大转盘中奖积分奖励
                //}

                #endregion

                #region 插入兑换记录 //

                //var guid = Guid.NewGuid();
                //var product = await PointProductManager.GetJC(res.LuckProduct.Kid);
                //var productsexchange = new T_ProductsExchange()
                //{
                //    F_UserKid = broker.Kid,
                //    F_ProductKid = res.LuckProduct.Kid,
                //    F_ExchangeTime = DateTime.Now,
                //    F_PointNum = -usePoint,
                //    F_IsDisplay = exchangeNotDisplay.Contains(res.LuckProduct.Name) ? 0 : 1,//1显示  0不显示
                //    F_OrderNo = DateTime.Now.ToString("yyyyMMddHHmmfff"),
                //    F_Guid = guid,
                //    F_IsStatus = autoList.Contains(res.LuckProduct.Name) ? 10 : (product.F_Status == 1 ? (int)ExchangeState.Checking : (int)ExchangeState.Succeed), //1:审核中 3：兑换成功
                //    F_ExchangeType = "幸运大转盘"
                //};
                //exchangeKid = await ProductsExchangeManager.Add(productsexchange, db);

                #endregion

                #region 针对约车卷 //

                //if (exchangeKid > 0 && res.LuckProduct.Name == "约车券")
                //{

                //    if (!string.IsNullOrEmpty(product.F_Source))
                //    {
                //        string postData = string.Format("brokerKid={0}&productCode={1}&exchangeId={2}&OrderNo={3}&guid={4}",
                //       productsexchange.F_UserKid,
                //       product.F_Code,
                //       exchangeKid,
                //       productsexchange.F_OrderNo,
                //       productsexchange.F_Guid);//商品编码，防伪码(不需要)
                //        string result = WebHelper.SendMsg(product.F_Source, postData);
                //        //将返回结果反序列化
                //        var resultJson = Top.Web.Json.ToObject<Result>(result);
                //        //判断获取约车券是否成功
                //        if (resultJson.code == 0) //如果成功，从返回结果中获得约车券
                //        {
                //            await ProductsExchangeManager.AppendRemark(exchangeKid, (string)resultJson.data);//将约车券的号码保存到备注
                //            await ProductsExchangeManager.SaveCarNo(exchangeKid, resultJson.data);//将约车券的号码保存到兑换说明
                //        }
                //        else//如果失败
                //        {
                //            //事务回滚
                //            db.Rollback();
                //            res.Message = "约车券生成失败";
                //            res.State = -7;
                //            res.LuckProduct = notWin;//感谢参与
                //            return res;
                //        }
                //    }
                //    else//如果失败
                //    {
                //        //事务回滚
                //        db.Rollback();
                //        res.Message = "约车券来源不能为空";
                //        res.State = -7;
                //        res.LuckProduct = notWin;//感谢参与
                //        return res;
                //    }
                //    //string postData = string.Format("brokerKid={0}&couponNum=1&source={1}&tag={2}&couponCode={3}&remark={4}&startTime={5}&endTime={6}&api={7}&exchangeId={8}", brokerKid, "RevokeTraining", 0, product.F_Code, "积分兑换约车券", exchangeRule.F_BeginTime, exchangeRule.F_EndTime, "api.get.broker.addbrokercarcouponrecord", exchangeKid);//商品编码，防伪码(不需要)
                //}

                #endregion

                #region 纪录中奖纪录 //

                //插入一条中奖纪录 异步
                //if (res.State > 0)
                //{
                //    T_LuckRecordExpand luckRecord = new T_LuckRecordExpand();
                //    luckRecord.BrokerKid = broker.Kid;
                //    luckRecord.ExchangeKid = exchangeKid;
                //    luckRecord.LuckProductKid = res.LuckProduct.Kid;
                //    luckRecord.OrderNo = DateTime.Now.ToString("yyyyMMddHHmmfff");
                //    luckRecord.UserName = broker.F_Title ?? broker.F_WX_Nickname;
                //    luckRecord.PhoneNumber = broker.F_Phone;
                //    luckRecord.F_CompanyName = broker.F_BrokerCompanyName;
                //    luckRecord.F_IsDisplay = luckRecordNotDisplay.Contains(res.LuckProduct.Name) ? 0 : 1;
                //    luckRecord.IsWin = winList.Contains(res.LuckProduct.Name) ? 1 : 0;
                //    luckRecord.CreateTime = DateTime.Now;
                //    await AddLuckyRecord(luckRecord,broker.Kid);
                //}

                #endregion


                ////提示信息
                //if (joinCount == 0)
                //{
                //    res.Message = "您还有一次机会喔!";
                //}
                return res;

                #endregion

            }
            catch (Exception ex)
            {
                res.Message = "抽奖人数过多，请稍候再试!";
                res.State = -9;
                res.isWin = false;
                res.LuckProduct = notWin;//感谢参与
                ErrorLog.WriteLog(ex);
                return res;
            }
            finally
            {
                int value = 0;
                if (!IsUserBuying.TryRemove(user.UserToken, out value))
                    IsUserBuying.TryRemove(user.UserToken, out value);
            }
        }


        /// <summary>
        /// 更新抽奖奖品库存
        /// </summary>
        /// <param name="kid"></param>
        /// <returns>
        /// 1、result > 0 统计正常
        /// 2、result <= 0 redis出现异常
        /// </returns>
        public static int UpdateCount(int kid)
        {
            try
            {
                if (dicLuckProducts.ContainsKey(kid))
                {
                    LuckProduct luckProduct = dicLuckProducts[kid];
                    if (luckProduct != null)
                    {
                        bool getLock = false;

                        try
                        {
                            spinLock.Enter(ref getLock);
                            if (luckProduct.Count > 0)
                            {
                                luckProduct.Count = luckProduct.Count - 1;
                                luckProduct.LuckCount = luckProduct.LuckCount + 1;
                            }
                        }
                        finally
                        {
                            if (getLock) spinLock.Exit();
                        }

                        return 1;
                    }
                }
                return -1;
            }
            catch (Exception ex)
            {
                //Trace.TraceError(string.Format("Redis操作 类名[LuckTurntableManager] 方法名[UpdateCount] 异常信息：{0}", ex.ToString()));
                Trace.TraceError(string.Format("cache操作 类名[LuckTurntableManager] 方法名[UpdateCount] 异常信息：{0}", ex.ToString()));
                return -1;
            }

            #region cache

            //try
            //{
            //    IList<LuckProduct> luckProductList = LuckTurntableManager.GetLuckProductList();
            //    foreach (var item in luckProductList)
            //    {
            //        if (item.Kid == kid && item.Count > 0 && item.LuckCount < item.MaxCount)
            //        {
            //            item.Count = item.Count - 1;
            //            item.LuckCount = item.LuckCount + 1;
            //            break;
            //        }
            //    }

            //    cacheUtil.AddObject(ProductKey.LuckProductList, luckProductList);
            //    return 1;
            //}
            //catch (Exception ex)
            //{
            //    //Trace.TraceError(string.Format("Redis操作 类名[LuckTurntableManager] 方法名[UpdateCount] 异常信息：{0}", ex.ToString()));
            //    Trace.TraceError(string.Format("cache操作 类名[LuckTurntableManager] 方法名[UpdateCount] 异常信息：{0}", ex.ToString()));
            //    return -1;
            //}

            #endregion

            #region redis

            //int resultID = 0;
            //try
            //{
            //    IList<LuckProduct> luckProductList = await GetLuckProductList();
            //    foreach (var item in luckProductList)
            //    {
            //        if (item.Kid == kid && item.Count > 0 && item.LuckCount < item.MaxCount)
            //        {
            //            item.Count = item.Count - 1;
            //            item.LuckCount = item.LuckCount + 1;
            //            break;
            //        }
            //    }

            //    if (await RedisProvider.StringSet(ProductKey.LuckProductList, Json.ToJsonString(luckProductList)))
            //    {
            //        resultID = 1;
            //    }
            //    else
            //    {
            //        resultID = 0;
            //    }

            //}
            //catch (Exception ex)
            //{
            //    Trace.TraceError(string.Format("Redis操作 类名[LuckTurntableManager] 方法名[UpdateCount] 异常信息：{0}", ex.ToString()));
            //    resultID = -1;
            //}
            //return resultID;

            #endregion

            #region sql

            //            const string sql = @"UPDATE [T_LuckProduct]
            //                                SET [Count] = [Count] - 1
            //            	                    ,[LuckCount] = [LuckCount] + 1
            //                                WHERE Kid ={0}
            //            	                    AND [Count] > 0
            //            	                    AND [LuckCount] < [MaxCount]";

            //            using (var db = new DbTour())
            //            {
            //                return await db.Sql(sql, kid).ExecuteNonQuery();
            //            }

            #endregion

        }

        /// <summary>
        /// 获取某个用户中奖次数
        /// </summary>
        /// <param name="brokerId"></param>
        /// <param name="luckProductName"></param>
        /// <returns>
        /// 1、result > 0 统计正常
        /// 2、result < 0 redis出现异常
        /// </returns>
        public static async Task<int> JoinCount(string userToken)
        {

            #region redis

            //            //try
            //            //{
            //            //    List<string> luckRecordListStr = await RedisProvider.ListRange(string.Format(ProductKey.LuckRecordListByUserKid, brokerId), 0, -1);
            //            //    return luckRecordListStr.Count();
            //            //}
            //            //catch (Exception ex)
            //            //{
            //            //    Trace.TraceError(string.Format("Redis操作 类名[LuckTurntableManager] 方法名[JoinCount] 异常信息：{0}", ex.ToString()));
            //            //    return -1;
            //            //}

            #endregion

            #region sql
            //            string sql = string.Empty;
            //            switch (brokerId % 4)
            //            {
            //                case 0:
            //                    sql = @"SELECT Count(1) iCount
            //                                        FROM T_LuckRecord
            //                                        where UserToken={0}
            //                                        and CreateTime > {1}
            //                                        and CreateTime < {2}";
            //                    break;
            //                case 1:
            //                    sql = @"SELECT Count(1) iCount
            //                                        FROM T_LuckRecord2
            //                                        where UserToken={0}
            //                                        and CreateTime > {1}
            //                                        and CreateTime < {2}";
            //                    break;
            //                case 2:
            //                    sql = @"SELECT Count(1) iCount
            //                                        FROM T_LuckRecord3
            //                                        where UserToken={0}
            //                                        and CreateTime > {1}
            //                                        and CreateTime < {2}";
            //                    break;
            //                case 3:
            //                    sql = @"SELECT Count(1) iCount
            //                                        FROM T_LuckRecord4
            //                                        where UserToken={0}
            //                                        and CreateTime > {1}
            //                                        and CreateTime < {2}";
            //                    break;
            //            }

            #endregion

            const string sql = @"SELECT Count(1) iCount
                                                    FROM T_LuckRecord_new
                                                    where UserToken={0}
                                                    and CreateTime > {1}
                                                    and CreateTime < {2}";

            using (var db = new DbTour())
            {
                return (await db.Sql(sql, userToken, DateTime.Now.Date, DateTime.Now.Date.AddDays(1)).ExecuteScalar<int>(0));
            }

        }

        /// <summary>
        /// 获取某个用户中奖的最后商品 是否是 再来一次
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="productKid"></param>
        /// <returns></returns>
        public static async Task<int> GetLuckRecord(string userToken, int productKid)
        {

            #region redis

            //T_LuckRecordExpand model = new T_LuckRecordExpand();
            //try
            //{

            //    List<string> luckRecordListStr = await RedisProvider.ListRange(ProductKey.LuckRecordList, 0, -1);
            //    if (luckRecordListStr.Count() <= 0)
            //    {
            //        return null;
            //    }

            //    List<T_LuckRecordExpand> luckProductList = new List<T_LuckRecordExpand>();
            //    foreach (var item in luckRecordListStr)
            //    {
            //        luckProductList.Add(Json.ToObject<T_LuckRecordExpand>(item));
            //    }
            //    DateTime startDate = DateTime.Now.Date;
            //    DateTime endDate = startDate.AddDays(1);
            //    model = luckProductList.Where(c => c.BrokerKid == brokerId && c.CreateTime >= startDate && c.CreateTime < endDate).OrderByDescending(x => x.CreateTime).SingleOrDefault<T_LuckRecordExpand>();
            //}
            //catch (Exception ex)
            //{
            //    Trace.TraceError(string.Format("Redis操作 类名[LuckTurntableManager] 方法名[GetLuckRecord] 异常信息：{0}", ex.ToString()));
            //}
            //return model;

            #endregion


            #region sql
//            string sql = string.Empty;
//            switch (brokerId % 4)
//            {
//                case 0:
//                    sql = @"select COUNT(1) iCount from (select TOP 1 LuckProductKid from T_LuckRecord l
//  left join T_PointProduct p on l.LuckProductKid=p.Kid
//                            where BrokerKid={0}
//                            and CreateTime > {1}
//                            and CreateTime < {2} 
//                            order by CreateTime desc) temp where temp.LuckProductKid={3}";
//                    break;
//                case 1:
//                    sql = @"select COUNT(1) iCount from (select TOP 1 LuckProductKid from T_LuckRecord2 l
//  left join T_PointProduct p on l.LuckProductKid=p.Kid
//                            where BrokerKid={0}
//                            and CreateTime > {1}
//                            and CreateTime < {2} 
//                            order by CreateTime desc) temp where temp.LuckProductKid={3}";
//                    break;
//                case 2:
//                    sql = @"select COUNT(1) iCount from (select TOP 1 LuckProductKid from T_LuckRecord3 l
//  left join T_PointProduct p on l.LuckProductKid=p.Kid
//                            where BrokerKid={0}
//                            and CreateTime > {1}
//                            and CreateTime < {2} 
//                            order by CreateTime desc) temp where temp.LuckProductKid={3}";
//                    break;
//                case 3:
//                    sql = @"select COUNT(1) iCount from (select TOP 1 LuckProductKid from T_LuckRecord4 l
//  left join T_PointProduct p on l.LuckProductKid=p.Kid
//                            where BrokerKid={0}
//                            and CreateTime > {1}
//                            and CreateTime < {2} 
//                            order by CreateTime desc) temp where temp.LuckProductKid={3}";
//                    break;
//            }

            #endregion

            const string sql = @"select COUNT(1) iCount from (select TOP 1 LuckProductKid from T_LuckRecord_new l
              left join T_PointProduct p on l.LuckProductKid=p.Kid
                                        where UserToken={0}
                                        and CreateTime > {1}
                                        and CreateTime < {2} 
                                        order by CreateTime desc) temp where temp.LuckProductKid={3}";
            using (var db = new DbTour())
            {
                return await db.Sql(sql, userToken, DateTime.Now.Date, DateTime.Now.Date.AddDays(1), productKid).ExecuteScalar<int>();
            }

        }

        public static async Task<bool> Update(List<LuckProductExpand> list)
        {
            #region redis

            try
            {
                dicLuckProducts.Clear();
                foreach (var item in list)
                {
                    dicLuckProducts.TryAdd(item.Kid, new LuckProduct()
                    {
                        Kid = item.Kid,
                        Angle = item.Angle,
                        Name = item.Name,
                        Chance = item.Chance,
                        Count = item.Count,
                        Point = item.Point,
                        Description = item.Description,
                        MaxCount = item.MaxCount,
                        LuckCount = item.LuckCount,
                        Rate = item.Rate
                    });
                    await LuckProductManager.Update(item);
                }


                //using (var db = DataBase.Reader())
                //{
                //    const string sql = @"select * from T_LuckProduct";
                //    List<LuckProduct> luckProductList = await db.Sql(sql).ToList<LuckProduct>();

                //    foreach (var item in luckProductList)
                //    {


                //    }
                //    //new Top.Common.TopCacheUtil().AddObject(ProductKey.LuckProductList, luckProductList);
                //}

                return true;

                //return await RedisProvider.StringSet(ProductKey.LuckProductList, Json.ToJsonString(list));
            }
            catch (Exception ex)
            {
                //Trace.TraceError(string.Format("Redis操作 类名[LuckProductManager] 方法名[Update] 异常信息：{0}", ex.ToString()));
                Trace.TraceError(string.Format("cache操作 类名[LuckProductManager] 方法名[Update] 异常信息：{0}", ex.ToString()));
                return false;
            }

            #endregion
        }


        public static async Task<bool> IsJoin(int brokerId, int count = 1)
        {
            //TODO 指定周期内
            const string sql = @"SELECT Count(1)
                            FROM T_LuckRecord
                            where BrokerKid={0}
                            and CreateTime > {1}
                            and CreateTime < {2}";
            using (var db = new DbTour())
            {
                return (await db.Sql(sql, brokerId, DateTime.Now.Date, DateTime.Now.Date.AddDays(1)).ExecuteScalar<int>(0)) >= count;
            }
        }

        public static async Task<bool> IsFirst(int luckProductKid)
        {
            const string sql = @"SELECT Count(1)
                            FROM T_LuckRecord
                            where LuckProductKid={0}
                            and CreateTime > {1}
                            and CreateTime < {2}";

            using (var db = new DbTour())
            {
                return (await db.Sql(sql, luckProductKid, DateTime.Now.Date, DateTime.Now.Date.AddDays(1)).ExecuteScalar<int>(0)) <= 0;
            }
        }

        //public static LuckProduct GetRand(List<LuckProduct> list)
        //{
        //    var chanceSum = list.Sum(d => d.Chance);
        //    var res = new LuckProduct();
        //    foreach (var luckProduct in list)
        //    {
        //        var random = new Random().Next(1, chanceSum);
        //        if (random <= luckProduct.Chance)
        //        {
        //            res = luckProduct;
        //            break;
        //        }
        //        else
        //        {
        //            chanceSum -= luckProduct.Chance;
        //        }
        //    }
        //    return res;
        //}

        //gc
        //public static LuckProduct GetRand(IList<LuckProduct> list)
        public static LuckProduct GetRand()
        {
            var temp = 0;
            var tempList = new List<Range>();

            #region //

            //foreach (var luckProduct in list)
            //{
            //    if (luckProduct.Chance > 0)
            //    {
            //        var range = new Range();
            //        range.LuckProduct = luckProduct;
            //        range.minValue = temp;
            //        temp += luckProduct.Chance;
            //        range.maxValue = temp;
            //        tempList.Add(range);
            //    }
            //}

            #endregion

            LuckProduct outLuckProduct = null;
            foreach (var luckProduct in dicLuckProducts)
            {
                if (luckProduct.Value.LuckCount == luckProduct.Value.MaxCount && luckProduct.Value.Count <= 0)
                {
                    dicLuckProducts.TryRemove(luckProduct.Key, out outLuckProduct);
                    continue;
                }

                if (luckProduct.Value.Chance > 0)
                {
                    var range = new Range();
                    range.LuckProduct = luckProduct.Value;
                    range.minValue = temp;
                    temp +=Convert.ToInt32(luckProduct.Value.Chance);
                    range.maxValue = temp;
                    tempList.Add(range);
                }
            }

            var random = new Random().Next(temp);
            LuckProduct res = null;
            foreach (var range in tempList)
            {
                if (random >= range.minValue && random <= range.maxValue)
                    res = range.LuckProduct;
            }
            return res;
        }

        public static async Task<string> GetBrokerName(int brokerKid)
        {
            const string sql = @"select 
              ifnull(b.F_Title,b.F_WX_Nickname) as userName 
              from T_Broker as b 
              where b.Kid={0}";
            using (var db = new DbTour())
            {
                return await db.Sql(sql, brokerKid).ExecuteScalar("");
            }
        }
        public static async Task<string> GetBrokerPhone(int brokerKid)
        {
            const string sql = @" select 
              b.F_Phone as Phone 
              from T_Broker as b 
              where b.Kid={0}";
            using (var db = new DbTour())
            {
                return await db.Sql(sql, brokerKid).ExecuteScalar("");
            }
        }

        public static async Task<string> GetCompanyName(int brokerKid)
        {
            const string sql = @" select 
              b.F_BrokerCompanyName
              from T_Broker as b 
              where b.Kid={0}";
            using (var db = new DbTour())
            {
                return await db.Sql(sql, brokerKid).ExecuteScalar("");
            }
        }

        public static string GetLuckRecordSql(int userKid)
        {
            int mode = userKid % 4;

            switch (mode)
            {
                case 0:
                    return @"INSERT INTO [T_LuckRecord]
		                    ([UserName]
		                    ,[PhoneNumber]
		                    ,[OrderNo]
		                    ,[BrokerKid]
		                    ,[ExchangeKid]
		                    ,[LuckProductKid]
		                    ,[F_IsDisplay]
		                    ,[F_CompanyName]
		                    ,[CreateTime]
		                    ,[IsWin])
	                    VALUES
		                    ({0:UserName}
		                    ,{0:PhoneNumber}
		                    ,{0:OrderNo}
		                    ,{0:BrokerKid}
		                    ,{0:ExchangeKid}
		                    ,{0:LuckProductKid}
		                    ,{0:F_IsDisplay}
		                    ,{0:F_CompanyName}
		                    ,{0:CreateTime}
		                    ,{0:IsWin});
                select LAST_INSERT_ID()";
                case 1:
                    return @"INSERT INTO [T_LuckRecord2]
		                    ([UserName]
		                    ,[PhoneNumber]
		                    ,[OrderNo]
		                    ,[BrokerKid]
		                    ,[ExchangeKid]
		                    ,[LuckProductKid]
		                    ,[F_IsDisplay]
		                    ,[F_CompanyName]
		                    ,[CreateTime]
		                    ,[IsWin])
	                    VALUES
		                    ({0:UserName}
		                    ,{0:PhoneNumber}
		                    ,{0:OrderNo}
		                    ,{0:BrokerKid}
		                    ,{0:ExchangeKid}
		                    ,{0:LuckProductKid}
		                    ,{0:F_IsDisplay}
		                    ,{0:F_CompanyName}
		                    ,{0:CreateTime}
		                    ,{0:IsWin});
                select LAST_INSERT_ID()";
                case 2:
                    return @"INSERT INTO [T_LuckRecord3]
		                    ([UserName]
		                    ,[PhoneNumber]
		                    ,[OrderNo]
		                    ,[BrokerKid]
		                    ,[ExchangeKid]
		                    ,[LuckProductKid]
		                    ,[F_IsDisplay]
		                    ,[F_CompanyName]
		                    ,[CreateTime]
		                    ,[IsWin])
	                    VALUES
		                    ({0:UserName}
		                    ,{0:PhoneNumber}
		                    ,{0:OrderNo}
		                    ,{0:BrokerKid}
		                    ,{0:ExchangeKid}
		                    ,{0:LuckProductKid}
		                    ,{0:F_IsDisplay}
		                    ,{0:F_CompanyName}
		                    ,{0:CreateTime}
		                    ,{0:IsWin});
                select LAST_INSERT_ID()";
                case 3:
                    return @"INSERT INTO [T_LuckRecord4]
		                    ([UserName]
		                    ,[PhoneNumber]
		                    ,[OrderNo]
		                    ,[BrokerKid]
		                    ,[ExchangeKid]
		                    ,[LuckProductKid]
		                    ,[F_IsDisplay]
		                    ,[F_CompanyName]
		                    ,[CreateTime]
		                    ,[IsWin])
	                    VALUES
		                    ({0:UserName}
		                    ,{0:PhoneNumber}
		                    ,{0:OrderNo}
		                    ,{0:BrokerKid}
		                    ,{0:ExchangeKid}
		                    ,{0:LuckProductKid}
		                    ,{0:F_IsDisplay}
		                    ,{0:F_CompanyName}
		                    ,{0:CreateTime}
		                    ,{0:IsWin});
                select LAST_INSERT_ID()";
                default:
                    return @"INSERT INTO [T_LuckRecord]
		                    ([UserName]
		                    ,[PhoneNumber]
		                    ,[OrderNo]
		                    ,[BrokerKid]
		                    ,[ExchangeKid]
		                    ,[LuckProductKid]
		                    ,[F_IsDisplay]
		                    ,[F_CompanyName]
		                    ,[CreateTime]
		                    ,[IsWin])
	                    VALUES
		                    ({0:UserName}
		                    ,{0:PhoneNumber}
		                    ,{0:OrderNo}
		                    ,{0:BrokerKid}
		                    ,{0:ExchangeKid}
		                    ,{0:LuckProductKid}
		                    ,{0:F_IsDisplay}
		                    ,{0:F_CompanyName}
		                    ,{0:CreateTime}
		                    ,{0:IsWin});
                select LAST_INSERT_ID()";
            }
        }

        /// <summary>
        /// 新增中奖纪录
        /// </summary>
        /// <param name="model"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        public static async Task<int> AddLuckyRecord(T_LuckRecordExpand model, OAuthUser user)
        {

            #region redis

            //try
            //{
            //    await RedisProvider.ListLPush(string.Format(ProductKey.LuckRecordListByUserKid, userKid), Json.ToJsonString(model));
            //    await RedisProvider.ListLPush(ProductKey.LuckRecordList, Json.ToJsonString(model));
            //    return 1;
            //}
            //catch (Exception ex)
            //{
            //    Trace.TraceError(string.Format("Redis操作 类名[LuckTurntableManager] 方法名[AddLuckyRecord] 异常信息：{0}", ex.ToString()));
            //    return 0;
            //}

            #endregion

            //string sql = GetLuckRecordSql(userKid);

            const string sql = @"INSERT INTO [T_LuckRecord_new]
            		                    ([UserName]
            		                    ,[PhoneNumber]
            		                    ,[OrderNo]
            		                    ,[UserToken]
            		                    ,[ExchangeKid]
            		                    ,[LuckProductKid]
            		                    ,[F_IsDisplay]
            		                    ,[F_CompanyName]
            		                    ,[CreateTime]
            		                    ,[IsWin])
            	                    VALUES
            		                    ({0:UserName}
            		                    ,{0:PhoneNumber}
            		                    ,{0:OrderNo}
            		                    ,{0:UserToken}
            		                    ,{0:ExchangeKid}
            		                    ,{0:LuckProductKid}
            		                    ,{0:F_IsDisplay}
            		                    ,{0:F_CompanyName}
            		                    ,{0:CreateTime}
            		                    ,{0:IsWin});
                            select LAST_INSERT_ID()";
            using (var db = new DbTour())
            {
                return await db.Sql(sql, model).ExecuteScalar<int>(0);
            }

        }

        public static async Task<IList<T_LuckRecordExpand>> GetLuckRecordList(Pager pager)
        {


            #region redis

            //List<T_LuckRecordExpand> luckProductList = new List<T_LuckRecordExpand>();
            //List<string> luckRecordListStr = await RedisProvider.ListRange(ProductKey.LuckRecordList, 0, 8);
            //if (luckRecordListStr.Count() <= 0)
            //{
            //    return luckProductList;
            //}
            //foreach (var item in luckRecordListStr)
            //{
            //    luckProductList.Add(Json.ToObject<T_LuckRecordExpand>(item));
            //}
            //DateTime startDate = DateTime.Now.Date;
            //DateTime endDate = startDate.AddDays(1);
            //return luckProductList.Where(c => c.F_IsDisplay == 1 && c.CreateTime >= startDate && c.CreateTime < endDate).ToList<T_LuckRecordExpand>();

            #endregion

            #region sql

            using (var db = new DbTour())
            {

                DateTime startDate = DateTime.Now.Date;
                DateTime endDate = startDate.AddDays(1);
                string sql = @"SELECT 
                                        l.LuckProductKid,
                                        l.UserName,
                                        l.PhoneNumber,
                                        l.CreateTime,
                                        l.F_CompanyName,
                                        ll.F_ProductName
                                        FROM T_LuckRecord AS l
                	                        inner join T_PointProduct as ll on l.LuckProductKid=ll.Kid
                                        WHERE l.F_CompanyName<>'' and l.F_IsDisplay = 1 and l.CreateTime >={0} and l.CreateTime<{1}
                ";
                return await db.Sql(sql, startDate, endDate).ToList<T_LuckRecordExpand>(pager.StartNumber, pager.EndNumber, "l.CreateTime desc");

            }

            #endregion

        }

        public static async Task<int> GetLuckCount()
        {
            #region redis

            //try
            //{
            //    List<string> luckRecordListStr = await RedisProvider.ListRange(ProductKey.LuckRecordList, 0, -1);
            //    return luckRecordListStr.Count();
            //}
            //catch (Exception ex)
            //{
            //    Trace.TraceError(string.Format("Redis操作 类名[LuckTurntableManager] 方法名[GetLuckCount] 异常信息：{0}", ex.ToString()));
            //    return 0;
            //}

            #endregion

            #region sql

            using (var db = new DbTour())
            {
                const string sql = @"select count(1) from T_LuckRecord where F_IsDisplay=1 and CreateTime > {0} and CreateTime < {1}";
                return await db.Sql(sql, DateTime.Now.Date, DateTime.Now.Date.AddDays(1)).ExecuteScalar<int>();
            }

            #endregion
        }

        public static async Task<IList<LuckRecord>> GetLuckRecordListByBrokerKid(int brokerKid, Pager pager)
        {
            if (brokerKid <= 0) return new List<LuckRecord>();
            const string sql = @"select top 50 *
                      from T_LuckRecord as l where BrokerKid={0}";

            using (var db = new DbTour())
            {
                return await db.Sql(sql, brokerKid).ToList<LuckRecord>(pager.StartNumber, pager.EndNumber, "l.Createtime desc");
            }
        }



        /// <summary>获取中奖记录列表
        /// </summary>
        /// <param name="phone"></param>
        /// <param name="brokerName"></param>
        /// <param name="sdt"></param>
        /// <param name="edt"></param>
        /// <param name="pager"></param>
        /// <returns></returns>
        public static async Task<IList<LuckRecord>> GetLuckList(int cityKid, int authCityKid, string phone, string brokerName, string sdt, string edt, int isSend, int isWin, string productName, Pager pager)
        {
            phone = phone.Trim();
            brokerName = brokerName.Trim();
            try
            {
                using (var db = new DbTour())
                {
                    var query = db.Table(@"SELECT a.*
        ,c.F_Address
        ,d.F_ProductName as NAME
        ,e.F_IsStatus as IsSend
    FROM T_LuckRecord a
    LEFT JOIN T_Broker b ON a.BrokerKid = b.Kid
    LEFT JOIN T_BrokerCompany c ON b.F_BrokerCompanyKid = c.Kid 
    inner JOIN T_PointProduct d ON a.LuckProductKid = d.Kid
    inner join T_ProductsExchange as e on e.Kid=a.ExchangeKid");

                    if (authCityKid != 0)
                    {
                        query.And(" b.F_CityKid = {0}", authCityKid);
                    }
                    else
                    {
                        if (cityKid > 0)
                        {
                            query.And(" b.F_CityKid = {0}", cityKid);
                        }
                    }
                    //List<int> frameworkKisList = await SystemManager.GetFrameworkKids(adminKid);
                    //if (frameworkKisList.Contains(1))
                    //{

                    //}
                    //else
                    //{
                    //    IList<AdminCityExpand> cityList = await SystemManager.GetCityListByAdminKid(adminKid);
                    //    List<int> kids = (from c in cityList select c.F_CityKid).ToList<int>();
                    //    if (kids.Any())
                    //    {
                    //        //string kidList = string.Join(",", kids);
                    //        query.And(" b.F_CityKid in ({0})", kids);
                    //    }
                    //}

                    //if (cityKid > 0)
                    //{
                    //    query.And(" b.F_CityKid = {0}", cityKid);
                    //}
                    if (isSend == 10)
                    {
                        query.And("e.F_IsStatus = {0}", (int)ExchangeState.Send);
                    }
                    else if (isSend == 9)
                    {
                        query.And("e.F_IsStatus in ({0})", new[] { "1", "3", "9" });
                    }

                    if (isWin >= 0)
                    {
                        if (isWin == 0)
                        {
                            query.And("IsWin is null");
                        }
                        else if (isWin == 1)
                        {
                            query.And("IsWin = {0}", isWin);
                        }
                    }
                    if (!string.IsNullOrEmpty(phone))
                    {
                        query.And("PhoneNumber like '%" + phone + "%'");
                    }
                    if (!string.IsNullOrWhiteSpace(brokerName))
                    {
                        query.And("UserName like '%" + brokerName + "%'");
                    }
                    if (!string.IsNullOrWhiteSpace(sdt))
                    {
                        query.And("CreateTime >= {0}", sdt);
                    }
                    if (!string.IsNullOrWhiteSpace(edt))
                    {
                        edt = Convert.ToDateTime(edt).AddDays(1).ToString();
                        query.And("CreateTime < {0}", edt);
                    }

                    if (!string.IsNullOrWhiteSpace(productName))
                    {
                        query.And("d.F_ProductName like '%" + productName + "%'");
                    }

                    return await query.ToList<LuckRecord>(pager.StartNumber, pager.EndNumber, "a.CreateTime desc");
                }
            }
            catch
            {
                return new List<LuckRecord>();
            }

        }

        /// <summary>
        /// 更新奖品发放状态
        /// </summary>
        /// <param name="id"></param>
        /// <param name="isSend"></param>
        /// <returns></returns>
        public static async Task<bool> UpdateSendStatus(int id, int isSend)
        {
            if (isSend == (int)ExchangeState.NotSend || isSend == (int)ExchangeState.Send)
            {
                using (var db = new DbTour())
                {
                    const string sql = "update T_ProductsExchange set F_IsStatus = {0} where Kid in (select ExchangeKid from T_LuckRecord where Kid={1})";
                    return await db.Sql(sql, isSend, id).ExecuteNonQuery() > 0;
                }
            }
            else
            {
                return false;
            }
        }



        public static async Task<LuckRecord> GetByExchangeKid(int exchangeKid)
        {
            const string sql = @"select 
l.*,e.F_ExchangeDescription,p.F_ProductName as Name
from T_LuckRecord as l
left join T_ProductsExchange as e on l.ExchangeKid=e.Kid
left join T_PointProduct as p on l.LuckProductKid=p.Kid
where e.Kid={0}";
            using (var db = new DbTour())
            {
                return await db.Sql(sql, exchangeKid).FirstOrDefault<LuckRecordExpan>();
            }
        }



        public static async Task<IList<T_ProductsExchangeExpand>> GetLuckRecordListByBrokerKid(Pager pager, int userKid)
        {
            using (var db = new DbTour())
            {

                DateTime startDate = DateTime.Now.Date;
                DateTime endDate = startDate.AddDays(1);
                string sql = @"SELECT  l.OrderNo,
        l.CreateTime as F_ExchangeTime,
        ll.F_ProductName,
        ll.F_PicUrl,
        100 as F_PointNum
        FROM T_LuckRecord AS l
       inner join T_PointProduct as ll on l.LuckProductKid=ll.Kid
        WHERE l.F_IsDisplay = 1 and l.CreateTime >={0} and l.CreateTime<{1} and l.BrokerKid = {2} ";
                return await db.Sql(sql, startDate, endDate, userKid).ToList<T_ProductsExchangeExpand>(pager.StartNumber, pager.EndNumber, "l.CreateTime desc");
            }

        }


        #region 中奖列表导出

        //        public static async Task<string> Export(string startTime, string endTime)
        //        {
        //            using (var db = new DbTour())
        //            {
        //                var query = db.Table(@"select
        //ISNULL(b.F_Title,b.F_WX_Nickname) as BrokerName,
        //b.F_Phone As BrokerPhone,
        //e.F_Name as CityName,
        //c.F_Title as BrokerCompanyName,
        //d.Name as AwardAmount
        //from T_LuckRecord a
        //left join T_Broker b on a.BrokerKid=b.Kid
        //left join T_BrokerCompany  c on b.F_BrokerCompanyKid=c.Kid
        //left join T_LuckProduct d on a.LuckProductKid=d.Kid 
        //left join T_ProvinceCityArea e on b.F_CityKid = e.Kid");

        //                if (!string.IsNullOrWhiteSpace(startTime))
        //                {
        //                    query.And("a.CreateTime >= {0}", startTime);
        //                }
        //                if (!string.IsNullOrWhiteSpace(endTime))
        //                {
        //                    endTime = Convert.ToDateTime(endTime).AddDays(1).ToString();
        //                    query.And("a.CreateTime < {0}", endTime);
        //                }

        //                IList<ExportLuckTurntable> resultList = await query.ToList<ExportLuckTurntable>();

        //                DataTable QueryResult = TopDataTableHelper.ToDataTable(resultList, LuckTurntableForExportFields());//获取要导出的列
        //                DataTable Export = TopDataTableHelper.CreateTable(LuckTurntableForExportTitle());//创建标头 
        //                foreach (DataRow dr in QueryResult.Rows)//导入数据
        //                {
        //                    Export.Rows.Add(dr["BrokerName"], dr["BrokerPhone"], dr["CityName"], dr["BrokerCompanyName"], dr["AwardAmount"]);
        //                }

        //                return CsvUtil.TableToScv(Export);
        //            }

        //        }


        public static async Task<string> Export(int cityKid, int adminKid, string phone, string brokerName, string startTime, string endTime, int isSend, int isWin, string productName)
        {
            using (var db = new DbTour())
            {
                var query = db.Table(@"SELECT
IfNULL(b.F_Title,b.F_WX_Nickname) as BrokerName,
b.F_Phone As BrokerPhone,
e.F_Name as CityName,
c.F_Title as BrokerCompanyName,
d.F_ProductName as AwardAmount
FROM T_LuckRecord a
LEFT JOIN T_Broker b ON a.BrokerKid = b.Kid
LEFT JOIN T_BrokerCompany c ON b.F_BrokerCompanyKid = c.Kid 
LEFT JOIN T_PointProduct d ON a.LuckProductKid = d.Kid
left join T_ProvinceCityArea e on b.F_CityKid = e.Kid
left join T_ProductsExchange f on a.ExchangeKid = f.Kid");

                query.And("b.F_Phone <>''");

                List<int> frameworkKisList = await SystemManager.GetFrameworkKids(adminKid);
                if (frameworkKisList.Contains(1))
                {

                }
                else
                {
                    IList<AdminCityExpand> cityList = await SystemManager.GetCityListByAdminKid(adminKid);
                    List<int> kids = (from c in cityList select c.F_CityKid).ToList<int>();
                    if (kids.Any())
                    {
                        //string kidList = string.Join(",", kids);
                        query.And(" b.F_CityKid in ({0})", kids);
                    }
                }

                if (cityKid > 0)
                {
                    query.And(" b.F_CityKid = {0}", cityKid);
                }

                if (isSend == 10)
                {
                    query.And("f.F_IsStatus = {0}", (int)ExchangeState.Send);
                }
                else if (isSend == 9)
                {
                    query.And("f.F_IsStatus in ({0})", new[] { "1", "3", "9" });
                }

                if (isWin >= 0)
                {
                    if (isWin == 0)
                    {
                        query.And("a.IsWin is null");
                    }
                    else if (isWin == 1)
                    {
                        query.And("a.IsWin = {0}", isWin);
                    }
                }

                if (!string.IsNullOrEmpty(phone))
                {
                    query.And("b.F_Phone like '%" + phone + "%'");
                }
                if (!string.IsNullOrWhiteSpace(brokerName))
                {
                    query.And("b.F_Title like '%" + brokerName + "%'");
                }

                if (!string.IsNullOrWhiteSpace(startTime))
                {
                    query.And("a.CreateTime >= {0}", startTime);
                }

                if (!string.IsNullOrWhiteSpace(endTime))
                {
                    endTime = Convert.ToDateTime(endTime).AddDays(1).ToString();
                    query.And("a.CreateTime < {0}", endTime);
                }

                if (!string.IsNullOrWhiteSpace(productName))
                {
                    query.And("d.F_ProductName like '%" + productName + "%'");
                }

                var result = await query.ExecuteDataTable();
                string path = string.Empty;
                DataTableExcel(result, string.Format("中奖名单（{0}）.xls", DateTime.Now.ToString("yyyy-MM-dd")), out path);
                //DataTable1Excel(result, GetMapPath("/Document/Template.xls"));
                return path;
            }

        }
        /// <summary>
        /// 导出Excel文件，并自定义文件名
        /// </summary>
        public static void DataTableExcel(DataTable dtData, String FileName, out string path)
        {
            string sitePath = "/Document/";
            string FilePathName = ProductsExchangeManager.GetMapPath(sitePath);
            DirectoryInfo info = Directory.CreateDirectory(FilePathName);
            FilePathName = FilePathName + FileName;
            //System.IO.File.Delete(FilePathName + FileName);
            FileStream Fs = new FileStream(FilePathName, FileMode.Create);
            StreamWriter BWriter = new StreamWriter(Fs, Encoding.UTF8);
            //将DataGrid的信息写入Excel文件 
            BWriter.Write(GetDataTableHtml(dtData));
            BWriter.Close();
            Fs.Close();
            path = sitePath + FileName;
        }

        public static string GetDataTableHtml(DataTable grid)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append("<table cellspacing=\"0\" rules=\"all\" border=\"1\" style=\"border-collapse:collapse;\">");
            sb.Append("<tr><td>经纪人姓名</td><td>联系电话</td><td>所属城市</td><td>所属公司</td><td>中奖金额</td></tr>");
            if (grid.Rows.Count > 0)
            {
                foreach (DataRow row in grid.Rows)
                {
                    sb.Append(@"<tr><td>" + (string.IsNullOrWhiteSpace(row["BrokerName"].ToString()) ? "" : row["BrokerName"]) +
                         "</td><td>" + (string.IsNullOrWhiteSpace(row["BrokerPhone"].ToString()) ? "" : row["BrokerPhone"]) +
                         "</td><td>" + (string.IsNullOrWhiteSpace(row["CityName"].ToString()) ? "" : row["CityName"]) +
                         "</td><td>" + (string.IsNullOrWhiteSpace(row["BrokerCompanyName"].ToString()) ? "" : row["BrokerCompanyName"]) +
                         "</td><td>" + (string.IsNullOrWhiteSpace(row["AwardAmount"].ToString()) ? "" : row["AwardAmount"]) +
                         "</td></tr>");
                }
            }
            else
            {
                sb.Append(@"<tr><td colspan='5' style='text-align:center'>未能找到相关信息</td></tr>");
            }
            sb.Append("</table>");

            return sb.ToString();
        }

        //public static void DataTable1Excel(DataTable dt, string path)
        //{
        //    if (dt.Rows.Count > 0)
        //    {
        //        Workbook workbook = new Workbook(); //工作簿 
        //        Worksheet sheet = workbook.Worksheets[0]; //工作表 
        //        Cells cells = sheet.Cells;//单元格 
        //        int Colnum = dt.Columns.Count;//表格列数 
        //        int Rownum = dt.Rows.Count;//表格行数 

        //        //生成行1 列名行 
        //        for (int i = 0; i < Colnum; i++)
        //        {
        //            //cells[0, i].PutValue(dt.Columns[i].ColumnName);
        //            cells[0, i].PutValue(LuckTurntableForExportTitle()[i]);
        //            cells.SetRowHeight(0, 25);
        //        }

        //        //生成数据行 
        //        for (int i = 0; i < Rownum; i++)
        //        {
        //            for (int k = 0; k < Colnum; k++)
        //            {
        //                cells[1 + i, k].PutValue(dt.Rows[i][k].ToString());
        //            }
        //            cells.SetRowHeight(1 + i, 24);
        //        }

        //        workbook.Save(path);
        //    }
        //}

        /// <summary>中奖列表表头
        /// </summary>
        /// <returns></returns>
        private static List<string> LuckTurntableForExportTitle()
        {

            return new List<string>()
            {
                "经纪人姓名",
                "类型电话",
                "所属城市",
                "所属公司",
                "中奖金额"
            };
        }

        public class ExportLuckTurntable
        {
            public string BrokerName { get; set; }
            public string BrokerPhone { get; set; }
            public string CityName { get; set; }
            public string BrokerCompanyName { get; set; }
            public string AwardAmount { get; set; }
        }

        #endregion


        public static async Task<bool> AddLog(Exception exMsg)
        {
            #region redis

            try
            {
                return await RedisProvider.ListLPush(LogKey.LogList, Json.ToJsonString(exMsg)) > 0;
            }
            catch (Exception ex)
            {
                Trace.TraceError(string.Format("Redis操作 类名[LuckTurntableManager] 方法名[AddLog] 异常信息：{0}", ex.ToString()));
                return false;
            }

            #endregion
        }


        public static async Task<IList<LuckProduct>> GetLuckProductList2()
        {
            using (var db = DataBase.Reader())
            {
                const string sql = @"select * from T_LuckProduct";
                return await db.Sql(sql).ToList<LuckProduct>();
            }
        }

    }

    public class Range
    {
        public int minValue { get; set; }
        public int maxValue { get; set; }
        public LuckProduct LuckProduct { get; set; }

    }
}
